﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace System.Windows.Media.Media3D10
{
    /// <summary>
    /// Matériau de rendu de nuit
    /// </summary>
    [System.Windows.Markup.ContentProperty("Brush")]
    public sealed class GlowMaterial : Material
    {
        #region Dependency Properties
        /// <summary>
        /// Identifie la propriété de dépendance <see cref="Brush"/>.
        /// </summary>
        public static readonly DependencyProperty BrushProperty =
            DependencyProperty.Register("Brush", typeof(Brush), typeof(GlowMaterial),
            new PropertyMetadata(new PropertyChangedCallback(Brush_PropertyChanged)));
        #endregion

        #region Contructors
        /// <summary>
        /// Initialise une nouvelle instance de la classe <see cref="GlowMaterial"/>
        /// </summary>
        public GlowMaterial()
            : base()
        { }

        /// <summary>
        /// Initialise une nouvelle instance de la classe <see cref="GlowMaterial"/> avec une texture
        /// </summary>
        /// <param name="brush">Texture à appliquer</param>
        public GlowMaterial(Brush brush)
            : base()
        {
            this.Brush = brush;
        }
        #endregion

        #region Data
        private const string glow_texture = "glow_texture";
        #endregion

        #region Dependency Properties Callbacks
        private static void Brush_PropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            if (object.ReferenceEquals(sender, null))
                throw new ArgumentNullException("sender");
            if (object.ReferenceEquals(e, null))
                throw new ArgumentNullException("e");
            (sender as GlowMaterial).OnBrushChanged(e);
        }
        #endregion

        #region Public Properties
        /// <summary>
        /// Texture à appliquer
        /// </summary>
        public Brush Brush
        {
            get { return (Brush)GetValue(BrushProperty); }
            set { SetValue(BrushProperty, value); }
        }
        #endregion

        #region Private Members
        private void OnBrushChanged(DependencyPropertyChangedEventArgs e)
        {
            if (object.ReferenceEquals(e, null))
                throw new ArgumentNullException("e");
            if (!object.ReferenceEquals(this.Effect, null))
                this.Effect.GetVariableByName(glow_texture).AsResource().SetTexture(Brush);
        }
        #endregion

        #region Material Overrides
        /// <summary>
        /// Appelé lors de l'initialisation de l'effet associé
        /// </summary>
        /// <param name="effect">Effet associé</param>
        protected override void OnInitEffect(SlimDX.Direct3D10.Effect effect)
        {
            base.OnInitEffect(effect);
            if (!object.ReferenceEquals(this.Effect, null))
            {
                this.Effect.GetVariableByName(glow_texture).AsResource().SetTexture(Brush);
            }
        }
        #endregion

        #region Freezable Implementation
        /// <summary>
        /// Une fois implémentée dans une classe dérivée, initialise une nouvelle instance de la classe dérivée <see cref="Freezable"/>. 
        /// </summary>
        /// <returns>Nouvelle instance.</returns>
        protected override Freezable CreateInstanceCore()
        {
            return new GlowMaterial();
        }
        #endregion
    }
}
